/**
 * Copyright 2010 The Regents of the University of California
 *
 *  All Rights Reserved
 */

#ifndef DCSWITCH_H
#define DCSWITCH_H 1

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <inttypes.h>

#include <openflow/openflow.h>
#include <pthread.h>
#include <assert.h>


// other constants/defines
#define ENABLE_STATS_ON "true"
#define ENABLE_STATS_OFF "false"

#define VM 1

#define CONTROLLER_OFPBUF_MSG_SERVER_PORT 7110
#define SECCHAN_OFPBUF_MSG_SERVER_PORT 7111

// Constants used in the implementation
#define UNICAST_FLOW_TIMEOUT 30
#define UNICAST_LIFETIME 6000
#define MULTICAST_LIFETIME 600
#define SCHEDULER_POLL_PERIOD 5
#define KEEPALIVE 0x8582

#define HOST_ID(x) ((((x) & 0x00FF0000)>>16) * 4 + (((x) & 0x0000FF00) >> 8) * 2 + ((x) & 0x000000FF) - 2)

#define K 6
#define MAX_SWITCHES 5*K*K/4
#define MAX_EDGE K*K/2
#define MAX_AGGR K*K/2
#define MAX_CORE K*K/4
#define MAX_HOSTS K*K*K/4
#define MAX_EDGE_HOSTS K/2

#define MAX_NUMBER_OF_SWITCHES 5*K*K/4
#define NUM_HOSTS 54
#define NUM_MULTICAST_STATE 25
#define ETH_ADDR_LEN 6
#define MAXMESG 128
#define MAX_DIST_UP 3
#define INF 100
#define UP 1
#define DOWN 0

#define L2_WILDCARDS (OFPFW_DL_SRC | OFPFW_NW_SRC_ALL | OFPFW_NW_DST_ALL | OFPFW_NW_PROTO | OFPFW_TP_SRC | OFPFW_TP_DST)

enum matchingState {PMAC = 10, 
		    PIP = 11 };

struct SwitchEntry {

    /**
     * the logical switch pointer
     */
    struct lswitch *sw;

    /**
     * The rconn to the switch
     */
    struct rconn *rc;

    /**
     * indicates whether the switch
     * is connected or not
     */
    bool connected;

    /**
     * identifier for a particular switch
     */
    uint64_t switchID;
    
};

typedef struct DCSwitchConfig {

    /**
     *
     */
    char *configFileName;

    /**
     * unique configuration ID
     */
    int configID;

    /**
     * A id generated for each run of the controller
     */
    time_t configRunID;

    /**
     * true (1) - indicates that stats should be collected
     * false (0) - indicates otherwise
     */
    bool statsEnabled;

    /**
     * The "k" constant for
     * all switches
     */
    int k;

    char FileName[100];

    bool insertDownwardFlowEntries;

    int idleTimeout;

    int hardTimeout;

    unsigned int flowEntryMatching;

    int probeTimeout;

}DCSwitchConfig;


typedef struct DCSwitchMsg {

    struct lswitch *sw;
    struct rconn *rc;
    struct ofpbuf *out;
} DCSwitchMsg;

int find_next_hop_switch_index(int sw_index, uint16_t output_port); 
int lookupSwitchIndex(uint64_t switchID);
void setConfigFile(char *fileName);
int DCSwitch_getK(void);
int getProbeTimeout(void);
unsigned int getFlowEntryMatching(void);
bool getInsertDownwardFlowEntries(void);
int DCSwitch_getK(void);
int getIdleTimeout(void);
int getHardTimeout(void);
DCSwitchConfig getDCSwitchConfig(void);


#endif
